package com.tiancheng.onecode.service.impl;

import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tiancheng.onecode.entity.PlatformMerchantSettleRule;
import com.tiancheng.onecode.enums.MerchantSettleRuleCycleTypeEnum;
import com.tiancheng.onecode.enums.MerchantSettleRuleStatusEnum;
import com.tiancheng.onecode.exception.Asserts;
import com.tiancheng.onecode.mapper.PlatformMerchantSettleRuleMapper;
import com.tiancheng.onecode.service.IMemberOrderService;
import com.tiancheng.onecode.service.IPlatformMerchantSettleRuleService;
import com.tiancheng.onecode.utils.IdWorkerUtils;
import com.tiancheng.onecode.utils.cache.SettleRulesCache;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * @Author: kellen
 * @Description: 商户清分规则表 service impl
 * @Date: create in 2024/12/13 15:48
 */
@Service
public class PlatformMerchantSettleRuleServiceImpl extends ServiceImpl<PlatformMerchantSettleRuleMapper, PlatformMerchantSettleRule> implements IPlatformMerchantSettleRuleService {

    @Resource
    private SettleRulesCache settleRulesCache;

    private IMemberOrderService getMemberOrderService(){
        return SpringUtil.getBean(IMemberOrderService.class);
    }

    /**
     * 增 - 新增即生效，同时把旧规则失效
     *
     * @param rule {@link PlatformMerchantSettleRule}
     * @return {@link Boolean}
     */
    @Transactional
    @Override
    public Boolean addRule(PlatformMerchantSettleRule rule) {
        // 1、查询生效的旧规则
        QueryWrapper<PlatformMerchantSettleRule> searchWrapper = new QueryWrapper<>();
        searchWrapper.eq("platform_merchant_id", rule.getPlatformMerchantId());
        searchWrapper.eq("org_payment_channel_id",rule.getOrgPaymentChannelId());
        searchWrapper.eq("rule_status", MerchantSettleRuleStatusEnum.EFFECTIVE.getValue());
        List<PlatformMerchantSettleRule> oldRules = this.list(searchWrapper);
        checkRule(rule);
        // 2、若有生效的旧规则，修改状态为“作废”，记录“规则失效时间”，记录最后操作人信息
        if (!CollectionUtils.isEmpty(oldRules)) {
            oldRules.forEach(d -> {
                d.setRuleStatus(MerchantSettleRuleStatusEnum.INVALIDATION.getValue());
                d.setExpireDate(LocalDateTime.now());
            });
            this.updateBatchById(oldRules, oldRules.size());
        }

        settleRulesCache.removeRuleFromCache(rule.getPlatformMerchantId());
        // 3、将新增的规则设置为“生效”，生成“规则编号”，记录创建人、更新人，插入数据库
        rule.setRuleStatus(MerchantSettleRuleStatusEnum.EFFECTIVE.getValue());
        rule.setRuleCode(IdWorkerUtils.getInstance().buildPartNumber());
        rule.setCreatedDt(LocalDateTime.now());
        return this.save(rule);
    }

    /**
     * 规则校验
     * @param rule
     */
    private void checkRule(PlatformMerchantSettleRule rule){
        Asserts.isTrue(null!=rule.getPlatformPercent() && rule.getPlatformPercent().compareTo(new BigDecimal(100))<1,"平台分佣百分比值不能为空，取值0-100！");
        Asserts.isTrue(null!=MerchantSettleRuleCycleTypeEnum.getByValue(rule.getCycleType()),"清分周期类型：T=按日（如T+1），M=按月固定日（如每月10日）");
        if(rule.getCycleType().equals(MerchantSettleRuleCycleTypeEnum.DAY.getValue())){
            Asserts.isTrue(null!=rule.getCycleValue()&& rule.getCycleValue()<=31,"按日清分，清分周期最长31天！");
        }
        if(rule.getCycleType().equals(MerchantSettleRuleCycleTypeEnum.MONTH.getValue())){
            Asserts.isTrue(null!=rule.getCycleValue()&& rule.getCycleValue()<=27,"按月清分，清分周期最大27！");
        }
    }

    @Override
    public Boolean updateRule(PlatformMerchantSettleRule rule) {
        checkRule(rule);
        PlatformMerchantSettleRule settleRule = this.getOne(new LambdaQueryWrapper<PlatformMerchantSettleRule>().eq(PlatformMerchantSettleRule::getRuleCode, rule.getRuleCode()));
        Asserts.isTrue(null!=settleRule && settleRule.getRuleStatus().equals(1),"规则不存在或规则状态为失效！");
        PlatformMerchantSettleRule updateRule = new PlatformMerchantSettleRule();
        updateRule.setId(settleRule.getId());
        updateRule.setPlatformPercent(rule.getPlatformPercent());
        updateRule.setCycleType(rule.getCycleType());
        updateRule.setCycleValue(rule.getCycleValue());
        updateRule.setRemark(rule.getRemark());
        updateRule.setLastUpdDt(LocalDateTime.now());
        return this.updateById(updateRule);
    }

    @Override
    public void deactivateSettlement(String ruleCode) {
        PlatformMerchantSettleRule settleRule = this.getOne(new LambdaQueryWrapper<PlatformMerchantSettleRule>().eq(PlatformMerchantSettleRule::getRuleCode, ruleCode));
        PlatformMerchantSettleRule d=new PlatformMerchantSettleRule();
        d.setId(settleRule.getId());
        d.setRuleStatus(MerchantSettleRuleStatusEnum.INVALIDATION.getValue());
        d.setExpireDate(LocalDateTime.now());
        this.updateById(d);
        settleRulesCache.removeRuleFromCache(settleRule.getPlatformMerchantId());
    }

    @Override
    public PlatformMerchantSettleRule queryByCode(String ruleCode) {
        QueryWrapper<PlatformMerchantSettleRule> searchWrapper = new QueryWrapper<>();
        searchWrapper.eq("rule_code", ruleCode);
        return this.getOne(searchWrapper);
    }

    @Override
    public List<PlatformMerchantSettleRule> queryByCodes(Set<String> ruleCode) {
        QueryWrapper<PlatformMerchantSettleRule> searchWrapper = new QueryWrapper<>();
        searchWrapper.in("rule_code", ruleCode);
        return this.list(searchWrapper);
    }

    @Override
    public PlatformMerchantSettleRule currentRule(Long platformMerchantId) {
        final List<PlatformMerchantSettleRule> rules = this.list(new LambdaQueryWrapper<PlatformMerchantSettleRule>().eq(PlatformMerchantSettleRule::getPlatformMerchantId, platformMerchantId)
                .eq(PlatformMerchantSettleRule::getRuleStatus, 1));
        return CollectionUtils.isEmpty(rules)?null:rules.get(0);
    }


}
